// import com.alibaba.druid.DbType;
// import com.alibaba.druid.sql.ast.SQLExpr_ptr;
// import com.alibaba.druid.sql.ast.SQLObject_ptr;
// import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
// import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.LinkedHashMap;
// import java.util.List;
// import java.util.Map;

#include "HiveCreateTableStatement.h"
#include "../../../visitor/SQLASTVisitor.h"
#include "../../../../utils/listTran.h"
#include "../../../ast/statement/SQLAssignItem.h"

HiveCreateTableStatement::HiveCreateTableStatement()
{
  this->dbType = DbType_ptr(new DbType(&DbType::hive));

  skewedBy = std::make_shared<std::list<SQLExpr_ptr>>();
  skewedByOn = std::make_shared<std::list<SQLExpr_ptr>>();
  serdeProperties = std::make_shared<std::map<std::string, SQLObject_ptr>>();
  mappedBy = std::make_shared<std::list<SQLAssignItem_ptr>>();
}

HiveCreateTableStatement::HiveCreateTableStatement(DbType_ptr dbType)
{
  this->dbType = dbType;

  skewedBy = std::make_shared<std::list<SQLExpr_ptr>>();
  skewedByOn = std::make_shared<std::list<SQLExpr_ptr>>();
  serdeProperties = std::make_shared<std::map<std::string, SQLObject_ptr>>();
  mappedBy = std::make_shared<std::list<SQLAssignItem_ptr>>();
}

void HiveCreateTableStatement::accept0(SQLASTVisitor_ptr v)
{
  if (v->visit(SharedObject(HiveCreateTableStatement)))
  {
    acceptChild(v);
  }
  v->endVisit(SharedObject(HiveCreateTableStatement));
}

void HiveCreateTableStatement::acceptChild(SQLASTVisitor_ptr v)
{
  SQLCreateTableStatement::acceptChild(v);

  SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLExpr, SQLObject>(skewedBy);
  SQLObjectImpl::acceptChild(v, tmp1);
  SQLObject_list_ptr tmp2 = ListTran::tran_class<SQLExpr, SQLObject>(skewedByOn);
  SQLObjectImpl::acceptChild(v, tmp2);
  for (auto item : *serdeProperties)
  {
    SQLObjectImpl::acceptChild(v, item.second);
  }
  SQLObjectImpl::acceptChild(v, metaLifeCycle);
  SQLObjectImpl::acceptChild(v, intoBuckets);
}

void HiveCreateTableStatement::cloneTo(HiveCreateTableStatement_ptr x)
{
  SQLCreateTableStatement::cloneTo(x);
  for (SQLExpr_ptr item : *skewedBy)
  {
    x->addSkewedBy(std::dynamic_pointer_cast<SQLExpr>(item->clone()));
  }
  for (SQLExpr_ptr item : *skewedByOn)
  {
    x->addSkewedByOn(std::dynamic_pointer_cast<SQLExpr>(item->clone()));
  }
  for (auto entry : *serdeProperties)
  {
    SQLObject_ptr entryValue = entry.second->clone();
    entryValue->setParent(x);
    x->serdeProperties->insert(std::make_pair(entry.first, entryValue));
  }
  if (metaLifeCycle != nullptr)
  {
    x->setMetaLifeCycle(std::dynamic_pointer_cast<SQLExpr>(metaLifeCycle->clone()));
  }

  x->setLikeQuery(this->likeQuery);

  if (mappedBy != nullptr)
  {
    for (SQLAssignItem_ptr item : *mappedBy)
    {
      SQLAssignItem_ptr item2 = std::dynamic_pointer_cast<SQLAssignItem>(item->clone());
      item2->setParent(SharedObject(HiveCreateTableStatement));
      x->mappedBy->push_back(item2);
    }
  }

  if (intoBuckets != nullptr)
  {
    x->intoBuckets = std::dynamic_pointer_cast<SQLExpr>(intoBuckets->clone());
  }

  if (using_ != nullptr)
  {
    x->setUsing(std::dynamic_pointer_cast<SQLExpr>(using_->clone()));
  }
}

SQLObject_ptr HiveCreateTableStatement::clone()
{

  SQLObject_ptr clone_tmp = std::shared_ptr<HiveCreateTableStatement>(new HiveCreateTableStatement());
  std::shared_ptr<HiveCreateTableStatement> x = std::dynamic_pointer_cast<HiveCreateTableStatement>(clone_tmp);
  // HiveCreateTableStatement x = new HiveCreateTableStatement();
  cloneTo(x);
  return x;
}

SQLExpr_list_ptr HiveCreateTableStatement::getSkewedBy()
{
  return skewedBy;
}

void HiveCreateTableStatement::addSkewedBy(SQLExpr_ptr item)
{
  item->setParent(SharedObject(HiveCreateTableStatement));
  this->skewedBy->push_back(item);
}

SQLExpr_list_ptr HiveCreateTableStatement::getSkewedByOn()
{
  return skewedByOn;
}

void HiveCreateTableStatement::addSkewedByOn(SQLExpr_ptr item)
{
  item->setParent(SharedObject(HiveCreateTableStatement));
  this->skewedByOn->push_back(item);
}

std::shared_ptr<std::map<std::string, SQLObject_ptr>> HiveCreateTableStatement::getSerdeProperties()
{
  return serdeProperties;
}

SQLExpr_ptr HiveCreateTableStatement::getMetaLifeCycle()
{
  return metaLifeCycle;
}

void HiveCreateTableStatement::setMetaLifeCycle(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(HiveCreateTableStatement));
  }
  this->metaLifeCycle = x;
}

BOOL_ptr HiveCreateTableStatement::isLikeQuery()
{
  return likeQuery;
}

void HiveCreateTableStatement::setLikeQuery(BOOL_ptr likeQuery)
{
  this->likeQuery = likeQuery;
}

SQLAssignItem_list_ptr HiveCreateTableStatement::getMappedBy()
{
  return mappedBy;
}

SQLExpr_ptr HiveCreateTableStatement::getIntoBuckets()
{
  return intoBuckets;
}

void HiveCreateTableStatement::setIntoBuckets(SQLExpr_ptr intoBuckets)
{
  this->intoBuckets = intoBuckets;
}

SQLExpr_ptr HiveCreateTableStatement::getUsing()
{
  return using_;
}

void HiveCreateTableStatement::setUsing(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(HiveCreateTableStatement));
  }
  this->using_ = x;
}
